"""
4.	利用OpenCV+Python环境，参照下列要求，完成视频图像的“车道线检测”任务（20分）


①	读取视频文件“lane.avi”第一帧，进行车道线检测处理
②	在颜色空间，正确选择车道线颜色及颜色范围
③	确定感兴趣区域ROI，利用OpenCV相应技术，图像进行必要的预处理
④	进行Hough直线变换，参数自定
⑤	处理完视频文件所有帧之后，保存车道线检测处理结果视频，并能够正常播放
"""
import cv2 as cv
import numpy as np
import os
import re
import datetime

np.random.seed(1)
VIDEO_PATH = 'data/lane_video/lane.avi'
VER = 'v1.0'
FPS = 25
INTERVAL = 1000 // FPS
VIDEO_SAVE_DIR = os.path.join('video_output', VER)
os.makedirs(VIDEO_SAVE_DIR, exist_ok=True)
regexp = re.compile('[^a-zA-Z0-9_]+')


def sep(label=''):
    print('-' * 32, label, '-' * 32)


def random_file_name():
    dt = str(datetime.datetime.now())
    dt = regexp.sub('_', dt)
    return dt

input_video = cv.VideoCapture(VIDEO_PATH)
W = int(input_video.get(cv.CAP_PROP_FRAME_WIDTH))
H = int(input_video.get(cv.CAP_PROP_FRAME_HEIGHT))
print('W, H', W, H)
output_path = os.path.join(VIDEO_SAVE_DIR, random_file_name() + '.avi')
fourcc = cv.VideoWriter_fourcc(*list('XVID'))
output_video = cv.VideoWriter(output_path, fourcc, FPS, (W, H))

print('Please press ESC on the drawing window to force an exiting.')
while True:
    ret, img = input_video.read()
    if not ret:
        print('Input video is over.')
        break

    # filter color
    hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    lower = (0, 0, 150)
    upper = (180, 50, 255)
    filtered = cv.inRange(hsv, lower, upper)

    # get roi
    mask = np.zeros((H, W), dtype=np.uint8)
    left_top = (W * 0.45, H / 2)
    right_top = (W * 0.6, H / 2)
    right_bottom = (W, H)
    left_bottom = (0, H)
    pts = np.int32([[left_top, right_top, right_bottom, left_bottom]])
    cv.fillPoly(mask, pts, 255)
    filtered = cv.bitwise_and(filtered, filtered, mask=mask)

    # canny borders
    filtered = cv.GaussianBlur(filtered, (5, 5), 0)
    canny = cv.Canny(filtered, 100, 200)

    # Hough lines
    lines = cv.HoughLinesP(canny, 1, np.pi/180, 20, maxLineGap=50)
    for line in lines:
        for x1, y1, x2, y2 in line:
            cv.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    cv.imshow('lane', img)

    output_video.write(img)
    k = cv.waitKey(INTERVAL) & 0xFF
    if k == 27:
        print('User fores an exiting.')
        break

input_video.release()
output_video.release()
cv.destroyAllWindows()
print('Over')
